#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
作者: jena 
创建时间: 2025.9
句子筛选算子 - 离线环境优化版本

"""
import re
import hashlib
import warnings
from collections import Counter, defaultdict
from typing import Dict, List, Set, Tuple, Optional, Union

# 导入配置和工具
try:
    from src.common_utils import safe_import
    from src.config import SentenceCleanerConfig
except ImportError:
    from .common_utils import safe_import
    from .config import SentenceCleanerConfig

# 离线环境jieba依赖管理
class JiebaDependencyManager:
    """jieba依赖管理器"""
    
    def __init__(self):
        self.jieba = None
        self._init_jieba()
    
    def _init_jieba(self):
        """初始化jieba - 只从offline_packages导入"""
        jieba_module, jieba_error = safe_import('jieba', 'jieba',
                                               "jieba不可用，基于分词的功能将被跳过")
        if jieba_module:
            try:
                # 直接使用safe_import返回的模块，不再重新导入
                self.jieba = jieba_module
                # 设置jieba为静默模式，避免初始化输出
                jieba_module.setLogLevel(20)  # WARNING级别
            except Exception as e:
                warnings.warn(f"jieba初始化失败: {e}")
        elif jieba_error:
            warnings.warn(jieba_error)
    
    def has_jieba(self) -> bool:
        """检查jieba是否可用"""
        return self.jieba is not None
    
    def get_jieba(self):
        """获取jieba模块"""
        return self.jieba
    
    def cut(self, text: str, cut_all: bool = False) -> List[str]:
        """安全的jieba分词"""
        if not self.has_jieba():
            # 回退方案：简单的字符分割
            return list(text)
        
        try:
            return list(self.jieba.cut(text, cut_all=cut_all))
        except Exception as e:
            warnings.warn(f"jieba分词失败: {e}")
            return list(text)

# 全局jieba依赖管理器实例
_jieba_deps = JiebaDependencyManager()


class SentenceCleaner:
    """
    ========== 句子级别的数据清洗 ==========
    
    【文本去重功能】- 多维度重复内容检测和过滤
    1. MD5哈希去重 (deduplicate_by_md5)
       • 基于MD5哈希值的精确重复检测
       • 高效处理大规模文本数据
       • 支持批量去重和统计
       • 适用场景：完全相同的文本内容去重
       • 性能特点：O(1)查找复杂度，内存占用小
    
    【长度控制功能】- 精确的文本长度管理
    2. 长度范围过滤 (filter_by_length)
       • 字符长度范围控制（min_length, max_length）
       • 词数统计和限制（字符模式或基于jieba分词的词模式）
       • 过滤过长或过短文本，确保文本长度在合适区间
       • 支持多种长度计算方式（字符数、jieba分词词数）
       • 过滤统计：过短、过长、合格文本数量
    
    【字段筛选功能】- 基于内容特征的智能过滤
    3. 字段条件过滤 (filter_by_fields)
       • 支持多字段条件筛选（包含、排除模式）
       • 灵活的过滤规则配置和组合（任一匹配、全部匹配）
       • 可配置大小写敏感性和jieba分词匹配
       • 适用于内容相关性筛选和主题过滤
    
    4. 结巴分词重复率过滤 (filter_by_jieba_repetition)
       • 基于jieba分词的语义重复检测
       • 可配置重复率阈值（0.0-1.0）
       • 智能识别近似重复内容
       • 计算方式：(总词数-唯一词数)/总词数
       • 适用场景：语义相似但表述略有差异的文本去重
       • 支持中文分词优化和停用词处理
    
    5. N-gram相似度过滤 (filter_by_ngram_similarity)
       • 基于jieba分词的词级n-gram特征相似性检测
       • 使用Jaccard相似度计算文本相似性
       • 可配置相似度阈值和n-gram参数（推荐n=2或3）
       • 专为中文文本优化，使用jieba分词进行词级特征提取
       • 适用场景：筛选掉相似度过高的文本，保持数据多样性
    
    
    【综合过滤功能】- 多条件组合过滤
    6. 综合句子过滤 (filter_sentences)
       • 集成所有过滤功能的统一接口
       • 按逻辑顺序执行：MD5去重→长度过滤→字段过滤→jieba分词重复过滤→n-gram相似度过滤
       • 支持配置对象(SentenceCleanerConfig)和参数传递
       • 5个独立开关控制各项功能
       • 详细的过滤原因记录和统计
    
    【批处理功能】- 高效的大规模数据处理
    7. 批量处理 (batch_filter_sentences)
       • 高效的批量数据处理和内存管理
       • 内存优化的流式处理模式
       • 支持多个文本批次的并行处理
       • 可配置批处理大小和处理策略
    
    【统计分析功能】- 全面的处理效果分析
    8. 统计信息管理 (get_stats, reset_stats, get_filter_summary)
       • 实时统计各类筛选操作数量
       • 分类统计：去重效果、过滤通过率、长度分布
       • 详细的过滤原因分析和报告
       • 支持处理效果可视化和质量监控
       • 提供过滤前后的数据对比分析
    

    
    ========== 核心算法特点 ==========
    • MD5去重：时间复杂度O(n)，空间复杂度O(n)
    • jieba重复率：时间复杂度O(nm)，m为平均词数
    • N-gram相似度：时间复杂度O(n²m)，适合中等规模数据
    • 字段过滤：支持jieba分词匹配，时间复杂度O(nm)
    • 长度过滤：时间复杂度O(n)，支持多种长度计算方式
    
    ========== 依赖库 ==========
    • jieba: 中文分词和文本分析（可选依赖，安全导入）
    • hashlib: MD5哈希计算和数据完整性校验
    • collections: 高效数据结构支持（Counter、defaultdict等）
    • re: 正则表达式模式匹配和文本处理
    • typing: 类型注解支持，提供更好的代码可读性
    • common_utils: 安全导入工具
    • config: SentenceCleanerConfig配置类


    """
    
    def __init__(self):
        # 初始化依赖管理器
        self._jieba_deps = _jieba_deps
        
        # MD5缓存
        self.md5_cache = set()
        
        # 统计信息
        self.stats = {
            # 总体统计
            'total_texts': 0,
            'final_texts': 0,
            
            # 去重处理统计
            'md5_duplicates_removed': 0,
            'unique_texts_processed': 0,
            
            # jieba分词重复过滤统计
            'jieba_filtered_texts': 0,
            'high_repetition_texts': 0,
            
            # n-gram相似度过滤统计
            'ngram_filtered_texts': 0,
            'similar_texts_removed': 0,
            
            # 字段过滤统计
            'field_filtered_texts': 0,
            'field_missing_texts': 0,
            
            # 长度过滤统计
            'length_filtered_texts': 0,
            'too_short_texts': 0,
            'too_long_texts': 0,
            
            # 综合处理统计
            'total_texts_processed': 0,
            'texts_passed_filter': 0
        }
        
   
    # ==================== 文本去重处理 ====================
    
    def deduplicate_by_md5(self, texts: List[str], update_cache: bool = True) -> List[str]:
        """
        MD5去重：利用MD5算法对文本进行哈希计算，识别并去除重复文本
        
        Args:
            texts: 待去重的文本列表
            update_cache: 是否更新内部MD5缓存
            
        Returns:
            去重后的文本列表
        """
        if not texts:
            return []
            
        unique_texts = []
        duplicates_count = 0
        
        for text in texts:
            # 只处理字符串类型
            if not isinstance(text, str) or not text or not text.strip():
                continue
                
            # 计算文本的MD5哈希值
            text_hash = hashlib.md5(text.encode('utf-8')).hexdigest()
            
            # 检查是否重复
            if text_hash not in self.md5_cache:
                unique_texts.append(text)
                if update_cache:
                    self.md5_cache.add(text_hash)
            else:
                duplicates_count += 1
        
        # 更新统计信息
        self.stats['md5_duplicates_removed'] += duplicates_count
        self.stats['unique_texts_processed'] += len(unique_texts)
        
        # 强制自动清除缓存 - 每次MD5去重后都清除
        self.clear_md5_cache()
        
        return unique_texts
    
    def is_duplicate_text(self, text: str) -> bool:
        """
        检查单个文本是否为重复文本
        
        Args:
            text: 待检查的文本
            
        Returns:
            True表示重复，False表示唯一
        """
        if not text or not text.strip():
            return True
            
        text_hash = hashlib.md5(text.encode('utf-8')).hexdigest()
        return text_hash in self.md5_cache
    
    def clear_md5_cache(self):
        """
        清空MD5缓存
        """
        self.md5_cache.clear()
    
    # ==================== 基于jieba分词的重复比率过滤 ====================
    
    def filter_by_jieba_repetition(self, texts: List[str], 
                                   repetition_threshold: float = 0.3,
                                   cut_all: bool = False) -> List[str]:
        """
        基于jieba分词的重复比率过滤：使用jieba对中文文本分词，过滤重复比率过高的文本
        
        Args:
            texts: 待过滤的文本列表
            repetition_threshold: 重复比率阈值（0-1之间）
            cut_all: 是否使用全模式分词（True为全模式，False为精确模式）
            
        Returns:
            过滤后的文本列表
        """
        if not texts:
            return []
            
        if not self._jieba_deps.has_jieba():
            print("Warning: jieba not available, skipping jieba repetition filtering")
            return texts
            
        filtered_texts = []
        high_repetition_count = 0
        
        for text in texts:
            if not text or not text.strip():
                continue
                
            repetition_ratio = self._calculate_jieba_repetition_ratio(
                text, cut_all
            )
            
            if repetition_ratio <= repetition_threshold:
                filtered_texts.append(text)
            else:
                high_repetition_count += 1
        
        # 更新统计信息
        self.stats['jieba_filtered_texts'] += len(filtered_texts)
        self.stats['high_repetition_texts'] += high_repetition_count
        
        return filtered_texts
    
    def _calculate_jieba_repetition_ratio(self, text: str, 
                                          cut_all: bool = False) -> float:
        """
        计算基于jieba分词的重复比率
        
        Args:
            text: 待分析的文本
            cut_all: 是否使用全模式分词
            
        Returns:
            重复比率（0-1之间的浮点数）
        """
        if not text or not text.strip():
            return 0.0
            
        if not self._jieba_deps.has_jieba():
            return 0.0
            
        try:
            # 使用统一的依赖管理器进行分词
            words = self._jieba_deps.cut(text.strip(), cut_all=cut_all)
            
            # 过滤掉空白词和标点符号
            words = [word.strip() for word in words if word.strip() and not re.match(r'^[\s\W]+$', word)]
            
            if len(words) < 2:
                return 0.0
                
            # 统计词频
            word_counts = Counter(words)
            total_words = len(words)
            unique_words = len(word_counts)
            
            # 计算重复比率：(总数-唯一数)/总数
            repetition_ratio = (total_words - unique_words) / total_words
            
            return repetition_ratio
            
        except Exception as e:
            print(f"jieba分词重复比率计算失败: {e}")
            return 0.0
    

    
    # ==================== 长度过滤 ====================
    
    def filter_by_length(self, texts: List[str],
                        min_length: int = 1,
                        max_length: int = 1000,
                        count_mode: str = 'char') -> List[str]:
        """
        长度过滤：按照文本整体长度进行筛选，过滤过长或过短文本
        
        Args:
            texts: 待过滤的文本列表
            min_length: 最小长度阈值
            max_length: 最大长度阈值
            count_mode: 计数模式，'char'为字符数，'word'为词数（使用jieba分词计算中文词数）
            
        Returns:
            过滤后的文本列表
        """
        if not texts:
            return []
            
        filtered_texts = []
        too_short_count = 0
        too_long_count = 0
        
        for text in texts:
            # 根据模式计算长度
            if count_mode == 'char':
                text_length = len(text)
            elif count_mode == 'word':
                if self._jieba_deps.has_jieba():
                    # 使用jieba分词计算中文词数
                    words = self._jieba_deps.cut(text.strip())
                    # 过滤掉空白词和标点符号
                    words = [word.strip() for word in words if word.strip() and not re.match(r'^[\s\W]+$', word)]
                    text_length = len(words)
                else:
                    # jieba不可用时回退到正则表达式
                    words = re.findall(r'\b\w+\b', text)
                    text_length = len(words)
            else:
                raise ValueError("count_mode must be 'char' or 'word'")
            
            # 长度筛选
            if min_length is not None and text_length < min_length:
                too_short_count += 1
            elif max_length is not None and text_length > max_length:
                too_long_count += 1
            else:
                filtered_texts.append(text)
        
        # 更新统计信息
        self.stats['length_filtered_texts'] += len(filtered_texts)
        self.stats['too_short_texts'] += too_short_count
        self.stats['too_long_texts'] += too_long_count
        
        return filtered_texts
    

    
    # ==================== N-gram相似度过滤 ====================
    
    def filter_by_ngram_similarity(self, texts: List[str],
                                  similarity_threshold: float = 0.8,
                                  n: int = 2) -> List[str]:
        """
        N-gram相似度过滤：基于jieba分词的n-gram特征相似性检测，筛选掉相似度过高的文本
        
        Args:
            texts: 待过滤的文本列表
            similarity_threshold: 相似度阈值（0-1之间），超过此值的文本将被过滤
            n: n-gram的n值（推荐2-3）
            
        Returns:
            过滤后的文本列表
        """
        if not texts or len(texts) <= 1:
            return texts
            
        filtered_texts = []
        filtered_ngrams = []  # 存储已保留文本的n-gram，避免重复查找
        similar_texts_count = 0
        
        for text in texts:
            if not text or not text.strip():
                continue
                
            # 提取当前文本的n-gram特征
            ngrams = set(self._extract_ngrams(text, n, 'word', True))
            is_similar = False
            
            # 与已保留的文本比较相似度
            for retained_ngrams in filtered_ngrams:
                similarity = self._calculate_jaccard_similarity(ngrams, retained_ngrams)
                if similarity > similarity_threshold:
                    is_similar = True
                    break
            
            if not is_similar:
                filtered_texts.append(text)
                filtered_ngrams.append(ngrams)
            else:
                similar_texts_count += 1
        
        # 更新统计信息
        self.stats['ngram_filtered_texts'] += len(filtered_texts)
        self.stats['similar_texts_removed'] += similar_texts_count
        
        return filtered_texts
    
    def _extract_ngrams(self, text: str, n: int, ngram_type: str = 'word', use_jieba: bool = True) -> List[str]:
        """
        提取文本的词级n-gram特征（基于jieba分词）
        
        Args:
            text: 待提取的文本
            n: n-gram的n值
            ngram_type: n-gram类型（固定为'word'，词级）
            use_jieba: 是否使用jieba分词（推荐True，适合中文）
            
        Returns:
            n-gram特征列表
        """
        if not text or not text.strip():
            return []
            
        text = text.strip()
        ngrams = []
        
        if ngram_type == 'word':
            # 词级n-gram
            if use_jieba and self._jieba_deps.has_jieba():
                words = self._jieba_deps.cut(text)
                words = [word.strip() for word in words if word.strip()]
            else:
                words = re.findall(r'\b\w+\b', text)
            
            for i in range(len(words) - n + 1):
                ngram = ' '.join(words[i:i+n])
                ngrams.append(ngram)
        else:
            raise ValueError("ngram_type must be 'word' for Chinese text processing")
            
        return ngrams
    
    def _calculate_jaccard_similarity(self, set1: Set[str], set2: Set[str]) -> float:
        """
        计算两个集合的Jaccard相似度
        
        Args:
            set1: 第一个集合
            set2: 第二个集合
            
        Returns:
            Jaccard相似度（0-1之间）
        """
        if not set1 and not set2:
            return 1.0
        if not set1 or not set2:
            return 0.0
            
        intersection = len(set1.intersection(set2))
        union = len(set1.union(set2))
        
        return intersection / union if union > 0 else 0.0
    

    
    # ==================== 特定字段过滤 ====================
    

    
    def filter_by_fields(self, texts: List[str],
                        target_fields: List[str],
                        filter_mode: str = 'include',
                        match_mode: str = 'any',
                        case_sensitive: bool = False,
                        use_jieba: bool = False) -> List[str]:
        """
        统一字段过滤：根据指定的字段信息进行筛选，支持保留或排除模式
        
        Args:
            texts: 待过滤的文本列表
            target_fields: 目标字段值列表
            filter_mode: 过滤模式，'include'表示保留包含字段的文本，'exclude'表示排除包含字段的文本
            match_mode: 匹配模式，'any'表示包含任一字段即匹配，'all'表示必须包含所有字段才匹配
            case_sensitive: 是否区分大小写
            use_jieba: 是否使用jieba分词进行匹配（更精确的中文匹配）
            
        Returns:
            过滤后的文本列表
        """
        if not texts or not target_fields:
            return texts
            
        if filter_mode not in ['include', 'exclude']:
            raise ValueError("filter_mode must be 'include' or 'exclude'")
            
        filtered_texts = []
        
        for text in texts:
            if not text:
                continue
                
            # 检查文本是否包含目标字段
            matches = []
            for field in target_fields:
                if not case_sensitive:
                    field = field.lower()
                    search_text = text.lower()
                else:
                    search_text = text
                    
                if use_jieba and self._jieba_deps.has_jieba():
                    # 使用jieba分词进行匹配，但检查字段是否作为子串出现在任何分词中
                    words = self._jieba_deps.cut(search_text)
                    # 检查字段是否完全匹配某个词，或者作为子串出现在某个词中
                    field_found = any(field == word or field in word for word in words)
                    matches.append(field_found)
                else:
                    # 简单字符串包含匹配
                    matches.append(field in search_text)
            
            # 根据匹配模式判断
            if match_mode == 'any':
                has_match = any(matches)
            else:  # 'all'
                has_match = all(matches)
            
            # 根据过滤模式决定是否保留
            if filter_mode == 'include' and has_match:
                filtered_texts.append(text)
                self.stats['field_filtered_texts'] += 1
            elif filter_mode == 'exclude' and not has_match:
                filtered_texts.append(text)
                self.stats['field_filtered_texts'] += 1
            else:
                self.stats['field_missing_texts'] += 1
        
        return filtered_texts
    
    
    def _check_text_contains_fields(self, text: str, 
                                   target_fields: List[str],
                                   case_sensitive: bool = False,
                                   use_jieba: bool = True) -> List[bool]:
        """
        检查文本是否包含指定的字段值
        
        Args:
            text: 待检查的文本
            target_fields: 必须包含的字段值列表
            case_sensitive: 是否区分大小写
            use_jieba: 是否使用jieba分词进行匹配
            
        Returns:
            布尔值列表，表示每个字段是否在文本中找到
        """
        if not text or not target_fields:
            return [False] * len(target_fields)
        
        # 预处理文本
        check_text = text if case_sensitive else text.lower()
        
        if use_jieba and self._jieba_deps.has_jieba():
            # 使用jieba分词进行精确匹配
            words = self._jieba_deps.cut(check_text)
            words = [word.strip() for word in words if word.strip()]
            word_set = set(words)
        
        results = []
        for field in target_fields:
            field_to_check = field if case_sensitive else field.lower()
            
            if use_jieba and self._jieba_deps.has_jieba():
                # 检查字段是否在分词结果中
                field_words = self._jieba_deps.cut(field_to_check)
                field_words = [word.strip() for word in field_words if word.strip()]
                
                # 首先尝试精确的分词匹配
                field_found = all(word in word_set for word in field_words) if field_words else False
                
                # 如果精确匹配失败，尝试子字符串匹配（处理复合词情况）
                if not field_found:
                    # 检查字段是否作为子字符串出现在任何分词中
                    field_found = any(field_to_check in word for word in words)
            else:
                # 简单的字符串包含检查
                field_found = field_to_check in check_text
            
            results.append(field_found)
        
        return results
    


    
    # ==================== 综合筛选接口 ====================
    
    def process_text(self, text: str,
                    config: Optional[SentenceCleanerConfig] = None,
                    **kwargs) -> str:
        """
        单文本筛选：对单个文本进行筛选处理
        
        Args:
            text: 待筛选的文本
            config: 筛选配置对象，如果为None则使用默认配置
            **kwargs: 兼容旧版本的参数，会被config覆盖
            
        Returns:
            筛选后的文本（如果通过筛选）或空字符串（如果被过滤）
        """
        if not text:
            return text
            
        result = self.filter_sentences([text], config, **kwargs)
        return result[0] if result else ""
    
    def process_texts(self, texts: List[str],
                     config: Optional[SentenceCleanerConfig] = None,
                     **kwargs) -> List[str]:
        """
        批量文本筛选：对文本列表进行筛选处理
        
        Args:
            texts: 待筛选的文本列表
            config: 筛选配置对象，如果为None则使用默认配置
            **kwargs: 兼容旧版本的参数，会被config覆盖
            
        Returns:
            筛选后的文本列表
        """
        return self.filter_sentences(texts, config, **kwargs)
    
    def filter_sentences(self, texts: List[str],
                        config: Optional[SentenceCleanerConfig] = None,
                        **kwargs) -> List[str]:
        """
        综合句子筛选：执行完整的文本筛选流程
        
        Args:
            texts: 待筛选的文本列表
            config: 过滤配置对象，如果为None则使用默认配置
            **kwargs: 兼容旧版本的参数，会被config覆盖
            
        Returns:
            筛选后的文本列表
        """
        if not texts:
            return []
        
        # 处理配置参数
        if config is None:
            # 从kwargs创建配置或使用默认值
            config = SentenceCleanerConfig(
                enable_md5_dedup=kwargs.get('enable_md5_dedup', False),
                enable_jieba_filter=kwargs.get('enable_jieba_filter', False),
                repetition_threshold=kwargs.get('repetition_threshold', 0.3),
                jieba_cut_all=kwargs.get('jieba_cut_all', False),
                enable_ngram_filter=kwargs.get('enable_ngram_filter', False),
                ngram_n=kwargs.get('ngram_n', 2),
                ngram_similarity_threshold=kwargs.get('ngram_similarity_threshold', 0.8),
                enable_field_filter=kwargs.get('enable_field_filter', False),
                target_fields=kwargs.get('target_fields', None),
                field_filter_mode=kwargs.get('field_filter_mode', 'include'),
                field_match_mode=kwargs.get('field_match_mode', 'any'),
                field_case_sensitive=kwargs.get('field_case_sensitive', False),
                field_use_jieba=kwargs.get('field_use_jieba', False),
                enable_length_filter=kwargs.get('enable_length_filter', False),
                min_length=kwargs.get('min_length', 1),
                max_length=kwargs.get('max_length', 1000),
                length_count_mode=kwargs.get('length_count_mode', 'char')
            )
            
        # 首先过滤出字符串类型的数据
        filtered_texts = [text for text in texts if isinstance(text, str)]
        original_count = len(texts)
        
        # 1. MD5去重
        if config.enable_md5_dedup:
            filtered_texts = self.deduplicate_by_md5(filtered_texts)
        
        # 2. 长度过滤
        if config.enable_length_filter:
            filtered_texts = self.filter_by_length(
                filtered_texts, config.min_length, config.max_length, config.length_count_mode
            )
        
        # 3. 字段过滤
        if config.enable_field_filter and config.target_fields:
            filtered_texts = self.filter_by_fields(
                filtered_texts,
                target_fields=config.target_fields,
                filter_mode=config.field_filter_mode,
                match_mode=config.field_match_mode,
                case_sensitive=config.field_case_sensitive,
                use_jieba=config.field_use_jieba
            )
        
        # 4. jieba重复度过滤
        if config.enable_jieba_filter:
            filtered_texts = self.filter_by_jieba_repetition(
                filtered_texts, config.repetition_threshold, config.jieba_cut_all
            )
        
        # 5. n-gram相似度过滤
        if config.enable_ngram_filter:
            filtered_texts = self.filter_by_ngram_similarity(
                filtered_texts,
                similarity_threshold=config.ngram_similarity_threshold,
                n=config.ngram_n
            )
        

        
        # 更新综合统计
        self.stats['total_texts'] = original_count
        self.stats['final_texts'] = len(filtered_texts)
        
        return filtered_texts
    
    def batch_filter_sentences(self, text_batches: List[List[str]], 
                             config: Optional[SentenceCleanerConfig] = None,
                             **kwargs) -> List[List[str]]:
        """
        批量筛选：对多个文本批次进行筛选
        
        Args:
            text_batches: 文本批次列表
            config: 筛选配置对象，如果为None则使用默认配置
            **kwargs: 兼容旧版本的参数，会被config覆盖
            
        Returns:
            筛选后的文本批次列表
        """
        filtered_batches = []
        
        for batch in text_batches:
            filtered_batch = self.filter_sentences(batch, config, **kwargs)
            filtered_batches.append(filtered_batch)
        
        return filtered_batches
    
    # ==================== 统计信息管理 ====================
    
    def get_stats(self) -> Dict[str, int]:
        """
        获取筛选统计信息
        
        Returns:
            包含各种筛选统计的字典
        """
        return self.stats.copy()
    
    def reset_stats(self):
        """
        重置统计信息
        """
        for key in self.stats:
            self.stats[key] = 0
    
    def get_filter_summary(self) -> Dict[str, any]:
        """
        获取筛选效果摘要
        
        Returns:
            包含筛选效果分析的字典
        """
        total_processed = self.stats['total_texts_processed']
        texts_passed = self.stats['texts_passed_filter']
        
        if total_processed == 0:
            return {
                'total_processed': 0,
                'texts_passed': 0,
                'filter_rate': 0.0,
                'duplicate_rate': 0.0,
                'repetition_filter_rate': 0.0,
                'length_filter_rate': 0.0
            }
        
        duplicate_rate = self.stats['md5_duplicates_removed'] / total_processed
        repetition_rate = self.stats['high_repetition_texts'] / total_processed
        length_filter_rate = (self.stats['too_short_texts'] + self.stats['too_long_texts']) / total_processed
        filter_rate = texts_passed / total_processed
        
        return {
            'total_processed': total_processed,
            'texts_passed': texts_passed,
            'filter_rate': filter_rate,
            'duplicate_rate': duplicate_rate,
            'repetition_filter_rate': repetition_rate,
            'length_filter_rate': length_filter_rate,
            'md5_duplicates_removed': self.stats['md5_duplicates_removed'],
            'high_repetition_texts': self.stats['high_repetition_texts'],
            'too_short_texts': self.stats['too_short_texts'],
            'too_long_texts': self.stats['too_long_texts']
        }